/**********************************************************************************************************
** 驱动文件：	dianli-EDA9033.c
** 驱动类型：	dianli
** 设备名称：	电力监测
** 设备型号：	EDA9033
** 设备品牌：	力创
** 设备协议：	Modbus
** 驱动描述：	三相导轨式多功能电力仪表，具备三相电压、电流、频率、电能、有功、无功等参数测量。
** 生成日期：	2018-05-17 13:47:53
**********************************************************************************************************/
#include "Includes.h"


/**********************************************************************************************************
* 定义设备数据点变量结构
**********************************************************************************************************/
typedef struct{
	Var Ua;										//A相电压
	Var Ub;										//B相电压
	Var Uc;										//C相电压
	Var Ia;										//A相电流
	Var Ib;										//B相电流
	Var Ic;										//C相电流
	Var Pa;										//A相有功
	Var Pb;										//B相有功
	Var Pc;										//C相有功
	Var Qa;										//A相无功
	Var Qb;										//B相无功
	Var Qc;										//C相无功
	Var P;										//总有功功率
	Var Q;										//总无功功率
	Var COS;									//功率因数
	Var Ep;										//总有功电能
	Var Eq;										//总无功电能
	Var Hz;										//频率
}Data_Struct;									//定义变量结构


/**********************************************************************************************************
* 设备数据点变量属性声明
**********************************************************************************************************/
const static Var_Property_Def var_attr[] = {
	{
		FLOAT,
		0,
		READONLY,
		"Ua",
		"A相电压",
		"V",
		"A相电压",
		0,
		0,
		"A相电压过高",
		"A相电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Ub",
		"B相电压",
		"V",
		"B相电压",
		0,
		0,
		"B相电压过高",
		"B相电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Uc",
		"C相电压",
		"V",
		"C相电压",
		0,
		0,
		"C相电压过高",
		"C相电压过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Ia",
		"A相电流",
		"A",
		"A相电流",
		0,
		0,
		"A相电流过高",
		"A相电流过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Ib",
		"B相电流",
		"A",
		"B相电流",
		0,
		0,
		"B相电流过高",
		"B相电流过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Ic",
		"C相电流",
		"A",
		"C相电流",
		0,
		0,
		"C相电流过高",
		"C相电流过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Pa",
		"A相有功",
		"W",
		"A相有功功率",
		0,
		0,
		"A相有功功率过高",
		"A相有功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Pb",
		"B相有功",
		"W",
		"B相有功功率",
		0,
		0,
		"B相有功功率过高",
		"B相有功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Pc",
		"C相有功",
		"W",
		"C相有功功率",
		0,
		0,
		"C相有功功率过高",
		"C相有功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Qa",
		"A相无功",
		"Var",
		"A相无功功率",
		0,
		0,
		"A相无功功率过高",
		"A相无功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Qb",
		"B相无功",
		"Var",
		"B相无功功率",
		0,
		0,
		"B相无功功率过高",
		"B相无功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Qc",
		"C相无功",
		"Var",
		"C相无功功率",
		0,
		0,
		"C相无功功率过高",
		"C相无功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"P",
		"总有功功率",
		"W",
		"总有功功率",
		0,
		0,
		"总有功功率过高",
		"总有功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Q",
		"总无功功率",
		"Var",
		"总无功功率",
		0,
		0,
		"总无功功率过高",
		"总无功功率过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"COS",
		"功率因数",
		"",
		"功率因数",
		0,
		0,
		"功率因数过高",
		"功率因数过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Ep",
		"总有功电能",
		"KW•h",
		"三相总有功电能",
		0,
		0,
		"总有功电能过高",
		"总有功电能过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Eq",
		"总无功电能",
		"KVar•h",
		"三相总无功电能",
		0,
		0,
		"总无功电能过高",
		"总无功电能过低",
		0,
		0
	},
	{
		FLOAT,
		0,
		READONLY,
		"Hz",
		"频率",
		"Hz",
		"频率",
		0,
		0,
		"频率过高",
		"频率过低",
		0,
		0
	}
};


/**********************************************************************************************************
* 函数名称： static void cmd_fun(short index, int addr, void *data, char *cmd, short *len)
* 函数说明： 生成获取传感器数据指令
* 输入参数： 指令索引，传感器地址，变量结构体指针,以及指令缓存区指针,指令长度
* 返回参数： 无
**********************************************************************************************************/
static void cmd_fun(short index, int addr, void *data, char *cmd, short *len)
{
	switch(index)
	{
		case 0:
			cmd[0] = addr;
			cmd[1] = 0x03;
			cmd[2] = 0x00;								
			cmd[3] = 0x00;
			cmd[4] = 0x00;	
			cmd[5] = 0x1f;
			*len = CRC16_Padding(cmd, 6);
			break;
		default:
			break;
	}
}


/**********************************************************************************************************
* 函数名称： static int parse_fun(short index, int addr, void *data, char *buf, short len)
* 函数说明： 解析传感器响应的数据，并写入数据库
* 输入参数： 解析索引,传感器地址，变量结构体指针，以及响应数据缓存取指针，响应数据长度
* 返回参数： 返回解析结果，返回0成功，返回1失败
**********************************************************************************************************/
static int parse_fun(short index, int addr, void *data, char *buf, short len)
{
	union{
		short 			dat16;
      	unsigned char  	dat8[2];
    }DAT16_8;						   //数据类型转换	
    union 		   					 
    {
		uint64_t  	dat64;
		unsigned char 	dat8[8];
    }value1,value2;							//数据类型转换		
	Data_Struct 	*d = (Data_Struct*)data;
	unsigned short	UBB , IBB;
	if(buf!=NULL && buf[0]==addr && len>0 )
	{	
		if(CRC16_Check(buf,len))
		{	
			UBB = buf[3]*buf[5]*2;
			IBB = buf[4]*buf[6];
			
			DAT16_8.dat8[1] = buf[7];
			DAT16_8.dat8[0] = buf[8];
			d->Ua.value.fnum = (DAT16_8.dat16*UBB)*0.0001;
		
			DAT16_8.dat8[1] = buf[9];
			DAT16_8.dat8[0] = buf[10];
			d->Ia.value.fnum = (DAT16_8.dat16*IBB)*0.0001;

			DAT16_8.dat8[1] = buf[11];
			DAT16_8.dat8[0] = buf[12];
			d->Ub.value.fnum = (DAT16_8.dat16*UBB)*0.0001;
		
			DAT16_8.dat8[1] = buf[13];
			DAT16_8.dat8[0] = buf[14];
			d->Ib.value.fnum = (DAT16_8.dat16*IBB)*0.0001;
		
			DAT16_8.dat8[1] = buf[15];
			DAT16_8.dat8[0] = buf[16];
			d->Uc.value.fnum = (DAT16_8.dat16*UBB)*0.0001;
		
			DAT16_8.dat8[1] = buf[17];
			DAT16_8.dat8[0] = buf[18];
			d->Ic.value.fnum = (DAT16_8.dat16*IBB)*0.0001;
					
			DAT16_8.dat8[1] = buf[19];
			DAT16_8.dat8[0] = buf[20];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->P.value.fnum = (DAT16_8.dat16*UBB*IBB*(-3))*0.0001;		
			}
			else
			{
				d->P.value.fnum = (DAT16_8.dat16*UBB*IBB*3)*0.0001;				
			}


			DAT16_8.dat8[1] = buf[21];
			DAT16_8.dat8[0] = buf[22];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->Q.value.fnum = (DAT16_8.dat16*UBB*IBB*(-3))*0.0001;	
			}
			else
			{
				d->Q.value.fnum = (DAT16_8.dat16*UBB*IBB*3)*0.0001;				
			}

			DAT16_8.dat8[1] = buf[23];
			DAT16_8.dat8[0] = buf[24];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->COS.value.fnum = ((-1)*DAT16_8.dat16)*0.0001;	
			}
			else
			{
				d->COS.value.fnum = DAT16_8.dat16*0.0001;
			}

			DAT16_8.dat8[1] = buf[25];
			DAT16_8.dat8[0] = buf[26];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->Pa.value.fnum = (DAT16_8.dat16*UBB*IBB*(-1))*0.0001;		
			}
			else
			{
				d->Pa.value.fnum = (DAT16_8.dat16*UBB*IBB)*0.0001;				
			}

			DAT16_8.dat8[1] = buf[27];
			DAT16_8.dat8[0] = buf[28];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->Pb.value.fnum = (DAT16_8.dat16*UBB*IBB*(-1))*0.0001;		
			}
			else
			{
				d->Pb.value.fnum = (DAT16_8.dat16*UBB*IBB)*0.0001;				
			}

			DAT16_8.dat8[1] = buf[29];
			DAT16_8.dat8[0] = buf[30];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->Pc.value.fnum = (DAT16_8.dat16*UBB*IBB*(-1))*0.0001;		
			}
			else
			{
				d->Pc.value.fnum = (DAT16_8.dat16*UBB*IBB)*0.0001;				
			}				

			DAT16_8.dat8[1] = buf[31];
			DAT16_8.dat8[0] = buf[32];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->Qa.value.fnum = (DAT16_8.dat16*UBB*IBB*(-1))*0.0001;	
			}
			else
			{
				d->Qa.value.fnum = (DAT16_8.dat16*UBB*IBB)*0.0001;				
			}
								
			DAT16_8.dat8[1] = buf[33];
			DAT16_8.dat8[0] = buf[34];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->Qb.value.fnum = (DAT16_8.dat16*UBB*IBB*(-1))*0.0001;	
			}
			else
			{
				d->Qb.value.fnum = (DAT16_8.dat16*UBB*IBB)*0.0001;				
			}				

			DAT16_8.dat8[1] = buf[35];
			DAT16_8.dat8[0] = buf[36];
			if(DAT16_8.dat8[1]&0x80)
			{
				DAT16_8.dat8[1]&=0x7f;
				d->Qc.value.fnum = (DAT16_8.dat16*UBB*IBB*(-1))*0.0001;	
			}
			else
			{
				d->Qc.value.fnum = (DAT16_8.dat16*UBB*IBB)*0.0001;				
			}

			DAT16_8.dat8[1] = buf[37];
			DAT16_8.dat8[0] = buf[38];
			d->Hz.value.fnum = DAT16_8.dat16*0.01;	

  			value1.dat8[7] = 0;
			value1.dat8[6] = 0;
  			value1.dat8[5] = buf[39];
			value1.dat8[4] = buf[40];
			value1.dat8[3] = buf[41];
			value1.dat8[2] = buf[42];
			value1.dat8[1] = buf[43];
			value1.dat8[0] = buf[44];

  			value2.dat8[7] = 0;
			value2.dat8[6] = 0;
  			value2.dat8[5] = buf[45];
			value2.dat8[4] = buf[46];
			value2.dat8[3] = buf[47];
			value2.dat8[2] = buf[48];
			value2.dat8[1] = buf[49];
			value2.dat8[0] = buf[50];
			d->Ep.value.fnum = (((value1.dat64-value2.dat64)*UBB*IBB)/1200000)*0.0001;

  			value1.dat8[7] = 0;
			value1.dat8[6] = 0;
  			value1.dat8[5] = buf[51];
			value1.dat8[4] = buf[52];
			value1.dat8[3] = buf[53];
			value1.dat8[2] = buf[54];
			value1.dat8[1] = buf[55];
			value1.dat8[0] = buf[56];

  			value2.dat8[7] = 0;
			value2.dat8[6] = 0;
  			value2.dat8[5] = buf[57];
			value2.dat8[4] = buf[58];
			value2.dat8[3] = buf[59];
			value2.dat8[2] = buf[60];
			value2.dat8[1] = buf[61];
			value2.dat8[0] = buf[62];
			d->Eq.value.fnum = (((value1.dat64-value2.dat64)*UBB*IBB)/1200000)*0.0001;
		}
		return 0;
	}
	return 1;
}


/**********************************************************************************************************
* 函数名称： void dianli_EDA9033_Registration(void)
* 函数说明： 电力监测驱动注册
* 输入参数： 无
* 返回参数： 无
**********************************************************************************************************/
void dianli_EDA9033_Registration(void)
{
	Device_Registration(
		"dianli",												//设备类型
		"电力监测",												//设备名称（导航栏默认显示名称）
		"EDA9033",												//设备型号
		"三相导轨式多功能电力仪表，具备三相电压、电流、频率、电能、有功、无功等参数测量。",//驱动描述
		var_attr,												//变量属性声明
		sizeof(Data_Struct),									//变量结构体空间大小
		cmd_fun,												//发送指令生成函数
		parse_fun												//数据解析函数
	);
}

